Implement --no-fail-fast flag for cargo test.
authorNicolas Koch <nioko1337@gmail.com>
Thu, 27 Aug 2015 02:58:09 +0000 (04:58 +0200)
committerNicolas Koch <nioko1337@gmail.com>
Fri, 28 Aug 2015 02:38:38 +0000 (04:38 +0200)
This flag can be used to force cargo to run all tests, even if previous
tests failed. See #1904

src/bin/bench.rs
src/bin/test.rs
src/cargo/ops/cargo_test.rs

index e4b5cac0c2e449492092ce7494ada071078040d3..932dae3108ff7374af85c1f12211cf4e3e80a0f7 100644 (file)
@@ -68,6 +68,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
 
     let ops = ops::TestOptions {
         no_run: options.flag_no_run,
+        no_fail_fast: false,
         compile_opts: ops::CompileOptions {
             config: config,
             jobs: options.flag_jobs,
index 8366a0badad6b5a7a1f0305516fbb6547ffe8001..ade460165289000a93ed476c8325a31f3494d0c7 100644 (file)
@@ -21,6 +21,7 @@ struct Options {
     flag_quiet: bool,
     flag_color: Option<String>,
     flag_release: bool,
+    flag_no_fail_fast: bool,
 }
 
 pub const USAGE: &'static str = "
@@ -47,6 +48,7 @@ Options:
     -v, --verbose            Use verbose output
     -q, --quiet              No output printed to stdout
     --color WHEN             Coloring: auto, always, never
+    --no-fail-fast           Run all tests regardless of failure
 
 All of the trailing arguments are passed to the test binaries generated for
 filtering tests and generally providing options configuring how they run. For
@@ -72,6 +74,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
 
     let ops = ops::TestOptions {
         no_run: options.flag_no_run,
+        no_fail_fast: options.flag_no_fail_fast,
         compile_opts: ops::CompileOptions {
             config: config,
             jobs: options.flag_jobs,
index 9fe2f02a1ccebd00dfbb6383875e811cb5a460ef..60077b06038815d35262bfe8ed687f6a5c5f1d70 100644 (file)
@@ -9,6 +9,7 @@ use util::{self, CargoResult, ProcessError};
 pub struct TestOptions<'a> {
     pub compile_opts: ops::CompileOptions<'a>,
     pub no_run: bool,
+    pub no_fail_fast: bool,
 }
 
 #[allow(deprecated)] // connect => join in 1.3
@@ -116,6 +117,7 @@ fn build_and_run<'a>(manifest_path: &Path,
     compile.tests.sort();
 
     let cwd = config.cwd();
+    let mut errors = Vec::new();
     for &(_, ref exe) in &compile.tests {
         let to_display = match util::without_prefix(exe, &cwd) {
             Some(path) => path,
@@ -131,9 +133,20 @@ fn build_and_run<'a>(manifest_path: &Path,
         }));
         match ExecEngine::exec(&mut ProcessEngine, cmd) {
             Ok(()) => {}
-            Err(e) => return Ok(Err(e))
+            Err(e) => {
+                errors.push(e);
+                if !options.no_fail_fast {
+                    break
+                }
+            }
         }
     }
+    if errors.is_empty() {
+        Ok(Ok(compile))
+    } else {
+        // errors.len() can be > 1, if --no-fail-fast is present.
+        // It would be cleaner to return the list of errors instead of just the last one.
+        Ok(Err(errors.pop().unwrap()))
+    }
 
-    Ok(Ok(compile))
 }